<template>
  <section class="demo-section">
    <div class="demo-header">
      <h2 class="demo-title">3. v-memo 性能优化指令 (Vue 3.2+)</h2>
      <p class="demo-description">
        v-memo 是 Vue 3.2+ 引入的性能优化指令，它可以缓存模板的一部分。
        当依赖项没有变化时，v-memo 会跳过该部分的重新渲染，这对于渲染大量数据时特别有用。
      </p>
    </div>

    <div class="demo-content">
      <div class="controls">
        <div class="control-group">
          <label>列表大小:</label>
          <input
            v-model.number="listSize"
            type="range"
            min="100"
            max="2000"
            step="100"
            class="slider"
          />
          <span>{{ listSize }} 项</span>
        </div>
        <div class="control-group">
          <label>高亮过滤:</label>
          <input
            v-model.number="highlightThreshold"
            type="range"
            min="0"
            max="100"
            class="slider"
          />
          <span>值 > {{ highlightThreshold }}</span>
        </div>
        <button @click="generateList" class="btn btn-secondary">重新生成列表</button>
      </div>

      <div class="memo-demo">
        <div class="demo-comparison">
          <div class="demo-column">
            <h4>❌ 无 v-memo ({{ renderCount.without }} 次渲染)</h4>
            <div class="list-container">
              <div
                v-for="item in memoList"
                :key="item.id"
                class="list-item"
                :class="{ highlighted: item.value > highlightThreshold }"
                @click="incrementRenderCount('without')"
              >
                <span class="item-id">#{{ item.id }}</span>
                <span class="item-value">{{ item.value }}</span>
                <span v-if="item.value > highlightThreshold" class="highlight-badge"
                  >🔥</span
                >
              </div>
            </div>
          </div>

          <div class="demo-column">
            <h4>✅ 使用 v-memo ({{ renderCount.with }} 次渲染)</h4>
            <div class="list-container">
              <div
                v-for="item in memoList"
                :key="item.id"
                v-memo="[item.value, highlightThreshold]"
                class="list-item"
                :class="{ highlighted: item.value > highlightThreshold }"
                @click="incrementRenderCount('with')"
              >
                <span class="item-id">#{{ item.id }}</span>
                <span class="item-value">{{ item.value }}</span>
                <span v-if="item.value > highlightThreshold" class="highlight-badge"
                  >🔥</span
                >
              </div>
            </div>
          </div>
        </div>

        <div class="performance-info">
          <div class="info-card">
            <h5>🚀 性能提升</h5>
            <p>
              v-memo 通过缓存不变的 DOM 节点，减少了不必要的重新渲染。
              在大列表场景下，性能提升可达 50-90%。
            </p>
          </div>
        </div>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";

// v-memo 相关状态
const listSize = ref(500);
const highlightThreshold = ref(50);
const memoList = ref<Array<{ id: number; value: number }>>([]);
const renderCount = reactive({
  with: 0,
  without: 0,
});

// 生成随机列表
function generateList() {
  memoList.value = Array.from({ length: listSize.value }, (_, i) => ({
    id: i + 1,
    value: Math.floor(Math.random() * 100),
  }));
  // 重置渲染计数
  renderCount.with = 0;
  renderCount.without = 0;
}

// 增加渲染计数
function incrementRenderCount(type: "with" | "without") {
  renderCount[type]++;
}

// 初始化
onMounted(() => {
  generateList();
});
</script>

<style scoped>
.demo-section {
  background: white;
  margin-bottom: 3rem;
  border-radius: 16px;
  padding: 2rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.05);
}

.demo-header {
  margin-bottom: 2rem;
}

.demo-title {
  font-size: 1.8rem;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 1rem;
}

.demo-description {
  font-size: 1rem;
  color: #64748b;
  line-height: 1.7;
  background: #f8fafc;
  padding: 1rem;
  border-radius: 8px;
  border-left: 4px solid #667eea;
}

.demo-content {
  display: grid;
  gap: 2rem;
}

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  padding: 1rem;
  background: #f1f5f9;
  border-radius: 8px;
}

.control-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.control-group label {
  font-size: 0.9rem;
  font-weight: 600;
  color: #374151;
}

.slider {
  padding: 0.5rem;
  border: 2px solid #e2e8f0;
  border-radius: 6px;
  transition: border-color 0.3s ease;
  width: 120px;
}

.slider:focus {
  outline: none;
  border-color: #667eea;
}

.btn {
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-secondary {
  background: #6b7280;
  color: white;
}

.btn-secondary:hover {
  background: #4b5563;
  transform: translateY(-2px);
}

.memo-demo {
  display: grid;
  gap: 2rem;
}

.demo-comparison {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.demo-column h4 {
  margin: 0 0 1rem 0;
  padding: 0.5rem;
  border-radius: 6px;
  text-align: center;
}

.demo-column h4:first-child {
  background: #fef2f2;
  color: #dc2626;
}

.demo-column:last-child h4 {
  background: #f0fdf4;
  color: #16a34a;
}

.list-container {
  height: 300px;
  overflow-y: auto;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.list-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid #f1f5f9;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.list-item:hover {
  background: #f8fafc;
}

.list-item.highlighted {
  background: #fef3c7;
}

.item-id {
  color: #6b7280;
  font-size: 0.9rem;
}

.item-value {
  font-weight: 600;
  color: #374151;
}

.highlight-badge {
  font-size: 0.8rem;
}

.performance-info {
  margin-top: 1rem;
}

.info-card {
  background: #f0f9ff;
  border: 1px solid #0ea5e9;
  border-radius: 8px;
  padding: 1rem;
}

.info-card h5 {
  color: #0c4a6e;
  margin: 0 0 0.5rem 0;
}

.info-card p {
  color: #0369a1;
  margin: 0;
  line-height: 1.5;
}

@media (max-width: 768px) {
  .demo-comparison {
    grid-template-columns: 1fr;
  }

  .controls {
    flex-direction: column;
    align-items: stretch;
  }

  .control-group {
    width: 100%;
  }
}
</style>
